#include <sys_head.h>
#include "sql_list.h"
/*
当新用户 加入群聊
    向所有用户发送 xxx 加入了群聊

新用户修改昵称 修改昵称
    新用户发送 set_name_名字

用户发送信息
    给出发送用户外的其他用户转发


如何实现
    线性表  链表 或者 顺序表

    顺序表

顺序表的结构

*/
void Server(int Sock_fd);

int main(int argc, char const *argv[])
{
    //判断命令行参数
    if (argc < 2)
    {
        printf("参数错误:%s ip port\n",argv[0]);
        return -1;
    }

    // 给定默认ip

    char ip_str[128];

    if ( 3 != argc )
    {
        
        strcpy( ip_str , "192.168.91.182");
    }
    else{
        
        strcpy( ip_str , argv[2]);
    }
    // 1、创建用户数据报 套接字
    int Udp_Sock_fd = socket(AF_INET,SOCK_DGRAM,0);

    // 2、填充服务器网络信息结构体
    struct sockaddr_in Udp_Sock_addr;
    Udp_Sock_addr.sin_family = AF_INET;
    Udp_Sock_addr.sin_port = htons(atoi(argv[1]));
    Udp_Sock_addr.sin_addr.s_addr = inet_addr(ip_str);

    socklen_t Udp_Sock_size = sizeof(Udp_Sock_addr);
    // 3、将套接字与服务器的网络信息结构体绑定
    bind(Udp_Sock_fd,(struct sockaddr *)&Udp_Sock_addr,Udp_Sock_size);
    // 4、收发数据
    Server(Udp_Sock_fd);
    
    // 5、关闭套接字
    close(Udp_Sock_fd);
    return 0;
}

void Server(int Sock_fd)
{
    //编写群聊

    struct sockaddr_in Udp_Sock_client;
    socklen_t Udp_Sock_client_size = sizeof(Udp_Sock_client);
    char buf[1024] = " ";//创建接收缓冲区
    char send_buf[2048] = " ";//创建发送缓冲区

    int find_index = 0;//创建一个变量用于记录客户端的个数

    //初始化顺序表
    UDP_client_sql *list = NULL;
    sql_list_init(&list);

    //定义数据
    UDP_client_data Client_data;

    while(1)
    {
        //清空数据
        memset(buf,0,sizeof(buf));
        memset(send_buf,0,sizeof(send_buf));
        memset(&Udp_Sock_client,0,sizeof(Udp_Sock_client));
        //接收数据
        recvfrom(Sock_fd,buf,sizeof(buf),0,(struct sockaddr *)&Udp_Sock_client,&Udp_Sock_client_size);
        
        Client_data.data = Udp_Sock_client;//将客户端信息存入结构体

        //添加用户
        if(NULL != strstr(buf,"new_"))
        {
            strcpy(Client_data.name,buf+4);

            //查找是否已经有这个用户
            if (-1 != sql_list_find(list,Client_data))
            {
                //有这个用户
                continue;;
            }
            else
            {
                sql_list_insert(list,Client_data,list->len + 1);
                //回发修改成功
                memset(buf,0,sizeof(buf));
                sprintf(buf,"%s 加入群聊",Client_data.name);
                for (size_t i = 0; i < list->len; i++)
                {
                    sendto(Sock_fd,buf,sizeof(buf),0,(struct sockaddr *)&list->data[i].data,sizeof(list->data[i].data));
                }
            }
        }
        //修改昵称
        else if (NULL != strstr(buf,"set_name_"))
        {
            //查找用户
            if (-1 == (find_index = sql_list_find(list, Client_data)))
            {
                break;
            }

            // 修改昵称
            sql_list_set_name(list, find_index, buf + 9);
        }
        else
        {
            // 组装字符串
            find_index = sql_list_find(list, Client_data);

            sprintf(send_buf, "%s : %s", list->data[find_index].name, buf);

            for (size_t i = 0; i < list->len; i++)
            {
                if (sql_list_cmp(list->data[i] , Client_data))
                {
                    sendto(Sock_fd, send_buf, strlen(send_buf), 0, (struct sockaddr *)&list->data[i].data, sizeof(list->data[i].data));
                }
            }
        }
    }
}